package controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.mybeans.form.FormBeanFactory;

import com.opentok.api.API_Config;
import com.opentok.api.OpenTokSDK;
import com.opentok.api.constants.RoleConstants;
import com.opentok.api.constants.SessionProperties;
import com.opentok.exception.OpenTokException;

import model.EmailDAO;
import model.Model;
import model.TokboxDAO;
import model.UserDAO;

import databean.Email;
import databean.Tokbox;
import databean.User;
import formbean.VideoCreateConfForm;


public class VideoCreateConfAction extends Action {
	
	private FormBeanFactory<VideoCreateConfForm> formBeanFactory = FormBeanFactory.getInstance(VideoCreateConfForm.class);
	
	private TokboxDAO tokboxDAO;
	private UserDAO   userDAO;
	private EmailDAO  emailDAO;


	public VideoCreateConfAction(Model model) {
		tokboxDAO = model.getTokboxDAO();
		userDAO   = model.getUserDAO();
		emailDAO  = model.getEmailDAO();
	}

	public String getName() { return "video-create-conf.do"; }

	public String perform(HttpServletRequest request,HttpServletResponse response) {
        
		// Set up the errors list
        List<String> errors = new ArrayList<String>();
        request.setAttribute("errors",errors);
        
        HttpSession session = request.getSession();
        
        
        //send email notification variables
        String subject = null;
        String sender = null;
        String recipient = null;
        String body = null;
        String timestamp = null;
        
        
		try {
	        
			if (session.getAttribute("user") == null) {
				return "user-login.do";
			}
	        
			request.setAttribute("user",(User) request.getSession(false).getAttribute("user"));
			

			VideoCreateConfForm form = formBeanFactory.create(request);
	        request.setAttribute("form",form);
	        
	        
	        
	        // If no params were passed, return with no errors so that the form will be
	        // presented (we assume for the first time).
	        if (!form.isPresent()) {
	        	
	        	//get a list of existing video conferences
			    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
			    request.setAttribute("tokboxes",tokboxes);
			    
			    ArrayList<User> users = userDAO.getAllUsers();
			    request.setAttribute("users",users);
			    
	        	return "video-existing-confs.jsp";
	        }

	        // Any validation errors?
	        errors.addAll(form.getValidationErrors());
	        if (errors.size() != 0) {
	        	
	        	//get a list of existing video conferences
			    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
			    request.setAttribute("tokboxes",tokboxes);
			    
			    ArrayList<User> users = userDAO.getAllUsers();
			    request.setAttribute("users",users);
			    
	        	return "video-existing-confs.jsp";
	        }

	        
	        // check if same conference name exists
	        if (tokboxDAO.hasConfNameExisted(form.getConfName())) {
	        	errors.add("Same conference name exists. Please change your conference name.");
	        	
	        	//get a list of existing video conferences
			    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
			    request.setAttribute("tokboxes",tokboxes);
			    
			    ArrayList<User> users = userDAO.getAllUsers();
			    request.setAttribute("users",users);
			    
	            return "video-existing-confs.jsp";
	        }
	        
	        
	        Tokbox tokbox = new Tokbox();
	        tokbox.setCreatorID(form.getCreatorID());
	        
	        //set creatorName
	    	User user = userDAO.getUserByUserID(Long.parseLong(tokbox.getCreatorID()));
	    	tokbox.setCreatorName(user.getFirstName() + " " + user.getLastName());
	    	sender = user.getEmail();
	        
	    	
	    	//getting attendeesID from view
	        int numOfUsers = userDAO.getAllUsers().size();
	        String formAttendeesID = "";
	        boolean firstTime = true;
	        for (int i=0; i<numOfUsers; i++) {
	        	if (request.getParameter("attendeesID[" + i + "]") != null) {
	        		if (firstTime) {
	        			formAttendeesID = request.getParameter("attendeesID[" + i + "]");
	        			firstTime = false;
	        		} else {
	        			formAttendeesID = formAttendeesID + "," + request.getParameter("attendeesID[" + i + "]");
	        		}
	        	}
	        }
	    	
	        tokbox.setConfName(form.getConfName());
	        tokbox.setAttendeesID(formAttendeesID);
	        
	        
	        //set attendeesNames
	        String[] attendeesID = tokbox.getAttendeesID().split(",");
	    	String attendeesNames = "";
	    	for (int j=0; j<attendeesID.length; j++) {
	    		
	    		if (!attendeesID[j].equals("")) {
		    		user = userDAO.getUserByUserID(Long.parseLong(attendeesID[j]));
		    		if (j==0) {
		    			attendeesNames = user.getFirstName() + " " + user.getLastName();
		    			recipient = user.getEmail();
		    		} else {
		    			attendeesNames = attendeesNames + "," + user.getFirstName() + " " + user.getLastName();
		    			recipient = recipient + "," + user.getEmail();
		    		}
	    		}
	    		
	    	}
	    	tokbox.setAttendeesNames(attendeesNames);
	    	
	        
	        tokbox.setNoteTakerID(form.getNoteTakerID());
	        
	        
	        //set notetakerName
	        user = userDAO.getUserByUserID(Long.parseLong(tokbox.getNoteTakerID()));
	    	tokbox.setNoteTakerName(user.getFirstName() + " " + user.getLastName());
	        
	    	
	        
	        Tokbox sessionTokbox;
	        try {
            	sessionTokbox = newSessionTokbox();
            } catch (Exception e) {
    			errors.add(e.getMessage());
    			
    			//get a list of existing video conferences
			    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
			    request.setAttribute("tokboxes",tokboxes);
			    
			    ArrayList<User> users = userDAO.getAllUsers();
			    request.setAttribute("users",users);
			    
	            return "video-existing-confs.jsp";
            }
	        
	        //set manually
	        tokbox.setExpired("false");
	        tokbox.setNotes("");
	        tokbox.setSessionID(sessionTokbox.getSessionID());
	        tokbox.setSessionIDLocal(sessionTokbox.getSessionIDLocal());
	        tokbox.setTokenModerator(sessionTokbox.getTokenModerator());
	        tokbox.setTokenPublisher(sessionTokbox.getTokenPublisher());
	        tokbox.setTokenSession(sessionTokbox.getTokenSession());
	        tokbox.setTokenSubscriber(sessionTokbox.getTokenSubscriber());
	        
	        
	        
	        // create a conference
	        tokboxDAO.create(tokbox);
	        
	        
	        
	        
	        
	        //////////////////////////////////////
	        // send email notifications - begin //
	        //////////////////////////////////////
	        
	        String inviter = userDAO.getUserByUserID(Long.parseLong(tokbox.getCreatorID())).getFirstName() 
	        				+ " " + userDAO.getUserByUserID(Long.parseLong(tokbox.getCreatorID())).getLastName();
	        subject = "Video Conference Invitation - " + tokbox.getConfName() + " has been created for you!";
	        body = inviter + " has created a video conference " + tokbox.getConfName() + " and invited you to join.<br><br>" +
	        		"Please click on <a href=video-existing-confs.do>Video Conference</a> tab to join this session at your convenience.";
	        
	        //timestamp
	        String format = "MM-dd-yyyy HH:mm:ss";
			TimeZone localZone = TimeZone.getDefault();
			String time = null;
			Calendar cal = Calendar.getInstance();
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			time= sdf.format(cal.getTime());
			timestamp = time+" "+localZone.getDisplayName();
	        
	        
	        ArrayList<String> emailToSend = new ArrayList<String>();
	        attendeesID = tokbox.getAttendeesID().split(",");
	    	for (int j=0; j<attendeesID.length; j++) {
	    		
	    		if (!attendeesID[j].equals("")) {
		    		user = userDAO.getUserByUserID(Long.parseLong(attendeesID[j]));
		    		emailToSend.add(user.getEmail());
	    		}
	    		
	    	}
	        
	    	for (int k=0; k<emailToSend.size(); k++) {
	    		
	    		Email notification = new Email();
		    	notification.setTimestamp(timestamp);
		    	notification.setUserID(userDAO.getUserIDByEmail(emailToSend.get(k)));
		    	notification.setOutlookID(emailToSend.get(k));
		    	notification.setSubject(subject);
		    	notification.setSender(sender);
		    	notification.setRecipient(recipient);			
		    	notification.setBody(body);
		    	notification.setNotes(null);
		    	notification.setStatus("Video Conference Invitation!");
		    	notification.setConversationID(EmailDAO.retrieveConversationID(notification));
		        
		        emailDAO.createEmail(notification);
		        
	    	}
	    	
	        
	        //////////////////////////////////////
	        // send email notifications - end   //
	        //////////////////////////////////////
	        
	        
	        
	        //get a list of existing video conferences
		    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
		    request.setAttribute("tokboxes",tokboxes);
		    
		    ArrayList<User> users = userDAO.getAllUsers();
		    request.setAttribute("users",users);
		    
            return "video-existing-confs.jsp";
	        
	        
        } catch (Exception e) {
        	errors.add(e.getMessage());
        	
        	//get a list of existing video conferences
		    ArrayList<Tokbox> tokboxes = tokboxDAO.getAllConfs();
		    request.setAttribute("tokboxes",tokboxes);
		    
		    ArrayList<User> users = userDAO.getAllUsers();
		    request.setAttribute("users",users);
		    
            return "video-existing-confs.jsp";
        }
        
    }
	
	
	public Tokbox newSessionTokbox() throws OpenTokException {

		Tokbox tokbox = new Tokbox();
	
		OpenTokSDK sdk = new OpenTokSDK(API_Config.API_KEY,API_Config.API_SECRET);

		
		
		//Generate a token
		String s = sdk.generate_token("session");
		tokbox.setTokenSession(s);
		
		s = sdk.generate_token("session",RoleConstants.PUBLISHER);
		tokbox.setTokenPublisher(s);
		
		s = sdk.generate_token("session",RoleConstants.SUBSCRIBER);
		tokbox.setTokenSubscriber(s);
		
		s = sdk.generate_token("session",RoleConstants.MODERATOR);
		tokbox.setTokenModerator(s);
		
		

		//Generate a basic session
		s = sdk.create_session().session_id;
		tokbox.setSessionID(s);

		
		
		//Generate Session Properties for a session
		SessionProperties sp = new SessionProperties();
		sp.echoSuppression_enabled = true;

		
		
		//Generate a session with a location hint and session properties
		s = sdk.create_session("127.0.0.1", sp).session_id;
		tokbox.setSessionIDLocal(s);

		return tokbox;
	}
	
}



